package com.jinghangzz.shop.head.interceptor;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jinghangzz.shop.common.controller.BaseController;
import com.jinghangzz.shop.common.util.ConstatFinalUtil;
import com.jinghangzz.shop.users.pojo.AUsers;
import com.jinghangzz.shop.users.pojo.AUsersCar;
import com.jinghangzz.shop.users.service.IUsersService;

/**
 * 用户的拦截器
 * @author TeaBig
 */
@Component("usersHeadAuthInterceptor")
public class UsersHeadAuthInterceptor extends BaseController implements HandlerInterceptor
{
	@Resource
	private IUsersService usersService;
	
	/**
	 * 执行Controller方法之前操作
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
	{
		ConstatFinalUtil.SYS_LOGGER.info("====UsersHeadAuthInterceptor preHandle====");
		HttpSession session = request.getSession() ; 
		/**
		 * session会话:会保持半个小时?
		 * 是依据的是浏览器的Cookie;
		 * 同一个浏览器,同一个服务,才是同一个会话(session)
		 */
		AUsers usersSess = (AUsers) session.getAttribute("users");
		if(usersSess != null)
		{
			/* 在什么时候往往session放了users;
			 * 严格把控
			 * 拿着token验证
			 * 跳转到登陆页,去登陆
			 *  */
			return true ; 
		}
		
		/*=============拿着token去用户中心验证是否正确性===============*/
		/* http://locahost:8080/aa/a.htm?a=1&a=2&a=3&a=4
		 * String a = request.getParameter("a");
		 * 
		 * 最新的是最后一个
		 *  */
		String[] tokens = request.getParameterValues("token");
		String token = ""; 
		if(tokens != null)
		{
			/* 取的是数组的最后一个 */
			token = tokens[tokens.length - 1];
		}
		
		if(!"".equalsIgnoreCase(token))
		{
			/* 有票,不管真伪,直接放行 */
			
			/* 网址 */
			String urlStr = ConstatFinalUtil.SYS_CONFIG_JSON.getString("usersCenter.outer.path") ; 
			/* 请求头 */
			Map<String, String> headerMap = new HashMap<String, String>();
			headerMap.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3732.400 QQBrowser/10.5.3824.400");
			/* 请求体 */
			Map<String, String> parameterMap = new HashMap<String, String>();
			
			/*
			 * 拼装json
	{
	    json的接口,最早是兴趣C(Client)S(Server)(json);B(Broswer)S(Server)(html因为浏览器只认html);
		// 版本;是为了兼容客户端运行的多个app版本;
		"version":"1",
		//方法名
		"method":"verifyUsersToken",
		// 公钥
		"pubKey":"",
		// 加密字符串
		"encrypt":"",
		// 存储数据
		"data":
		{
			// 令牌(票)
			"token":"5b0d685f-77b6-4acd-9788-73ac10dd972f"
		}
	}
			 * */
			JSONObject reqJSON = new JSONObject();
			reqJSON.put("version", "1");
			reqJSON.put("method", "verifyUsersToken");
			reqJSON.put("pubKey", "1");
			reqJSON.put("encrypt", "1");
			
			JSONObject dataReqJSON = new JSONObject();
			dataReqJSON.put("token", token);
			
			reqJSON.put("data", dataReqJSON);
			parameterMap.put("json", reqJSON.toJSONString());
			/* 响应头 */
			Map<String, String> responseMap = new HashMap<String, String>();
			/* 请求 */
			String responseStr = httpUtil.methodPost(urlStr, headerMap, parameterMap, responseMap);
			ConstatFinalUtil.SYS_LOGGER.info("urlStr:{}",urlStr);
			ConstatFinalUtil.SYS_LOGGER.info("请求头:{}",headerMap);
			ConstatFinalUtil.SYS_LOGGER.info("请求体:{}",parameterMap);
			ConstatFinalUtil.SYS_LOGGER.info("响应头:{}",responseMap);
			ConstatFinalUtil.SYS_LOGGER.info("响应体:{}",responseStr);
			JSONObject responseJSON = (JSONObject) JSON.parse(responseStr);
			/* 只有用户中心返回的json,code为0时,成功,其它全部失败; */
			if(responseJSON != null && "0".equalsIgnoreCase(responseJSON.get("code") + ""))
			{
				/* 获取数据 */
				JSONObject dataResJSON = responseJSON.getJSONObject("data");
				/* 获取用户 */
				JSONObject usersJSON = (JSONObject) dataResJSON.get("users");
				/* 应该做什么?
				 * 应该对AUsers表进行crud
				 * ~拿着用户中心返回的用户信息,去当前的系统用户表里面查询一下;
				 * 如果有:就更新一下相关的时间;
				 * 如果木有:就添加一条
				 *  */
				int ssoId = usersJSON.getIntValue("id");
				String email = usersJSON.getString("email");
				String trueName = usersJSON.getString("trueName");
				String lastLoginTime = usersJSON.getString("lastLoginTime");
				
				/* 判断,如果存在,就更新,如果不存在,就添加 */
				Map<String, Object> condMap = new HashMap<String, Object>();
				
				condMap.clear();
				condMap.put("ssoId", ssoId);
				AUsers users = this.usersService.findOneUsersService(condMap);
				/* 断言:假设;
				 * updateFlag:true;数据库中存在,肯定要更新;
				 * false:表示数据库中木有,需要添加
				 *  */
				boolean updateFlag = true; 
				if(users == null)
				{
					/* 木有查询到,要保存 */
					users = new AUsers();
					users.setCreateTime(new Date());
					updateFlag = false ; 
				}
				
				/* 一一的设置值 */
				users.setSsoId(ssoId);
				users.setEmail(email);
				users.setTrueName(trueName);
				users.setLastLoginTime(this.dateUtil.strToDateTime(lastLoginTime));
				users.setUpdateTime(new Date());
				
				/* 如何实现,木有,保存,有更新 */
				JSONObject resultJSON = new JSONObject();
				if(updateFlag)
				{
					/* 要更新 */
					resultJSON = this.usersService.updateOneUsersService(users);
				}else
				{
					/* 要添加 */
					resultJSON = this.usersService.saveOneUsersService(users);
				}
				ConstatFinalUtil.SYS_LOGGER.info("登陆结果:{}",resultJSON.toJSONString());
				/* 把用户的信息放到session中 */
				session.setAttribute("users", users);
				/* ==============将Cookie中的购物车合并到数据库============== */
				mergeCart(users,request,response);
				return true ; 
			}
		}
		
		/*=============跳转到登陆页面===============*/
		/* 当前访问的网址 */
		String returnUrl = request.getRequestURL().toString() ; 
		String queryStr = request.getQueryString() ; 
		if(queryStr == null)
		{
			queryStr = "";
		}
		if(!"".equalsIgnoreCase(queryStr))
		{
			returnUrl = returnUrl + "?" + queryStr ; 
		}
		/* 让链接直接跳转到用户中心的登陆页面 */
		String usersCenterLogin = ConstatFinalUtil.SYS_CONFIG_JSON.getString("usersCenter.login");
		ConstatFinalUtil.SYS_LOGGER.info("url:{};returnUrl:{}",usersCenterLogin,returnUrl);
		/* 如果returnURL有问题,得先url编码 */
		returnUrl = URLEncoder.encode(returnUrl,"UTF-8");
		usersCenterLogin = usersCenterLogin + "&returnUrl=" + returnUrl;
		ConstatFinalUtil.SYS_LOGGER.info("usersCenterLogin:{}",usersCenterLogin);
		response.sendRedirect(usersCenterLogin);
		return false;
	}

	/**
	 * 合并购物车
	 * @param users
	 * @param request
	 * @param response
	 * @throws Exception 
	 */
	private void mergeCart(AUsers users, HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		ConstatFinalUtil.SYS_LOGGER.info("==mergeCart==");
		/*--从Cookie中获取数据---*/
		/* 键 */
		String name = "goodsList";
		/* 只要看到值可以存储字符串的时候,统一使用JSON
[
	{"gid":"","num":""},
	{"gid":"","num":""},
	{"gid":"","num":""},
]
		 *  */
		String value = "" ; 
		Cookie cookieTarget = null ; 
		
		boolean cookieFlag = false; 
		/* 获取Cookie */
		Cookie[] cookieReq = request.getCookies();
		if(cookieReq != null)
		{
			for (int i = 0; i < cookieReq.length; i++)
			{
				Cookie cookieTemp = cookieReq[i];
				String nameTemp = cookieTemp.getName() ; 
				String valTemp = cookieTemp.getValue() ; 
				if(nameTemp.equalsIgnoreCase(name))
				{
					/* 得找我们当时存储的名字 */
					value = URLDecoder.decode(valTemp,"UTF-8");
					cookieTarget = cookieTemp ; 
					cookieFlag = true ; 
					break ; 
				}
			}
		}
		
		JSONArray goodsListArr = new JSONArray();
		if(cookieFlag)
		{
			/* 购物车有数据库 */
			goodsListArr = JSON.parseArray(value);
			if(goodsListArr == null)
			{
				goodsListArr = new JSONArray();
			}
		}
		
		Map<String, Object> condMap = new HashMap<String, Object>();
		/* 一边循环goodsListArr,一边往usersCarList中放东西 */
		for (Iterator iterator = goodsListArr.iterator(); iterator.hasNext();)
		{
			JSONObject goodsTempJSON = (JSONObject) iterator.next() ;
			String gid = goodsTempJSON.getString("gid");
			String numOld = goodsTempJSON.getString("num");
			/* 期望用户id和goodsId,要是查询到数据库里面有,就更新,木有就添加 */
			/*
			 * 断言:
			 * updateFlag:true,表示数据库中已经存在,需要更新,
			 * false:表示数据库中不存在,需要添加
			 * */
			boolean updateFlag = true ; 
			condMap.clear();
			condMap.put("usersId", users.getId());
			condMap.put("goodsId", gid);
			AUsersCar usersCar = this.usersService.findOneUsersCarService(condMap);
			if(usersCar == null)
			{
				/* 说明木有查询到 */
				usersCar = new AUsersCar();
				usersCar.setCreateTime(new Date());
				updateFlag = false ; 
			}
			
			usersCar.setUsersId(users.getId());
			usersCar.setGoodsId(Integer.valueOf(gid));
			/* 数据相加 */
			usersCar.setNum(usersCar.getNum() + Integer.valueOf(numOld));
			
			usersCar.setStatus(Byte.valueOf("1"));
			usersCar.setUpdateTime(new Date());
			usersCar.setPubTime(new Date());
			
			/* 存在的时候更新,不存在的时候添加 */
			JSONObject resultDbJSON = new JSONObject();
			if(updateFlag)
			{
				/* 更新 */
				resultDbJSON = this.usersService.updateOneUsersCarService(usersCar);
			}else
			{
				/* 添加 */
				resultDbJSON = this.usersService.saveOneUsersCarService(usersCar);
			}
			ConstatFinalUtil.SYS_LOGGER.info("合并购物车结果:{}",resultDbJSON);
		}
		
		if(cookieTarget != null)
		{
			cookieTarget.setValue("");
			/* 对Cookie做一些设置 */
			cookieTarget.setPath(request.getContextPath());
			/* 把Cookie添加到浏览器中 */
			response.addCookie(cookieTarget);
		}
	}
}
